const KoaRouter = require('@koa/router');
const router = new KoaRouter({ prefix: '/' });
const multer = require('@koa/multer');
const upload = multer();
const fs = require('fs');
const path = require('path');

// 上传文件目录
const target = path.resolve(__dirname, '../target');

// 临时文件目录
const tempPath = path.resolve(target, './temp');

// 保存状态
const state = { isMerge: false, currentSize: 0 };

const { pipeStream, recombinationFileName, extractExt } = require('../utils/files');
const { HOST, PORT } = require('../const');

router.post('verify', async ctx => {
    const { fileHash, filename } = ctx.request.body;

    const ext = extractExt(filename);
    const filePath = path.resolve(target, `${fileHash}${ext}`);

    if (fs.existsSync(filePath)) {
        ctx.body = {
            shouldUpload: false
        };
    } else {
        ctx.body = {
            shouldUpload: true
        };
    }
});
router.post(
    '/',
    upload.fields([
        {
            name: 'chunk'
        }
    ]),
    async (ctx, next) => {
        const { hash, totalSize } = ctx.request.body;
        const { chunk } = ctx.request.files;

        state.currentSize += chunk[0].size || 0;

        if (!fs.existsSync(target)) {
            await fs.promises.mkdir(target);
        }

        if (!fs.existsSync(tempPath)) {
            await fs.promises.mkdir(tempPath);
        }

        const filePath = path.resolve(tempPath, `./${hash}`);

        await fs.promises.writeFile(filePath, chunk[0].buffer, { encoding: 'binary' });
        if (state.currentSize >= totalSize && !state.isNoMerge) {
            state.isMerge = true;
            await next(ctx);
        }
        ctx.body = { status: '分片写入成功！' };
    },
    async ctx => {
        const { filename, fileHash } = ctx.request.body;

        console.log(ctx.request.body);

        if (!fs.existsSync(target)) {
            await fs.promises.mkdir(target);
        }
        const files = await fs.promises.readdir(tempPath);

        const needMergeFile = files.filter(item => item.startsWith(fileHash)).sort((a, b) => {
            const arr1 = a.split('-');
            const arr2 = b.split('-');

            return parseFloat(arr1[arr1.length - 1]) - parseFloat(arr2[arr2.length - 1]);
        });

        const filePath = path.resolve(target, recombinationFileName(fileHash, filename));
        const servePath = path.join(`${HOST}:${PORT}`, recombinationFileName(fileHash, filename));

        await Promise.all(
            needMergeFile.map((chunkName, index) => {
                return pipeStream(
                    path.resolve(tempPath, chunkName),
                    filePath,
                    index
                );
            }
            )
        );
        let mapJSON = require('../map.json');

        if (typeof mapJSON === 'object') {
            mapJSON.push({ filename, servePath: 'http://' + servePath });
        } else {
            mapJSON = [{ filename, servePath: 'http://' + servePath }];
        }
        await fs.promises.writeFile(path.resolve(__dirname, '../map.json'), JSON.stringify(mapJSON));

        // 上传完毕，清理操作

        state.currentSize = 0;
        state.isMerge = false;
        fs.rmdirSync(tempPath);
        ctx.body = { status: '上传完成' };
    }
);

module.exports = router;